/**
 * class name: itab,
 * copyright: maximus zhang,
 * License: MIT-LICENSE,
 * contact: maximus.zhang@gmail.com,
 * required-js: http://jsease.googlecode.com/svn/trunk/core.js,
 * update: http://jsease.googlecode.com/svn/trunk/itab.js
 * -------
 * todo: remove tab; key; tab moving; tab pull out as popup; popup to tab
 */
function itab(){/* {id,elem,css,{tabs}} */
    var A = arguments,
        _ = this;
    _ = ext( _, ext( {
        id : 'itab'+ now(3),
        elem : me.body,
        target: me.body,
        css : '',
        ttl : 600,
        icourl:'',
        tabclose: '/icos/ishut.gif',
        tabs : [
            {
                id:'newtab1',
                notab : false,
                rtl: false,
                tab : { label:'', cls:'', css:'' },
                ico : {src:'', css:'', alt:''},
                fn : function(){},
                key : '',
                data : '',
                locked : false,
                ttl : null
            }
        ] }, A[0]) );

    _.uitype = 'itab';

    _.elem = $(_.elem) || me.body;
    _.target = $(_.target) || me.body;

    _.$ = {};/* store tab's data element */
    _.tab$ = {};/* store tabs json data */
    _.timer = {};

    _.active = null;
    _.num = 0;

    _.timeout = function(a){
        if ( !a || !a.nodeName=='DD' ) {
            return false;
        }

        var id = a.id;//attr(a,'tabkey');

        if ( id=='' ) {
            return false;
        }

        if ( hop(_.timer, id) ) {
            var ttl = typeof _.tab$[id].ttl=='number'
                ? _.tab$[id].ttl
                : _.ttl;

            if ( parseInt((now(2)-_.timer[id])/1000, 10)>= ttl ) {
                delete _.timer[id];
                return true;
            }
        }

    return false;
    };

    _.go = function(a){

        if ( typeof a=='string' ) {
            if ( !hop(_.tab$, a) ) {
                return false;
            }

            var a = $(a/* _.tab$[a].id */);
        } else if ( typeof a == 'object' && a ) {
            if ( !hop(_.tab$, a.id) ) {
                _.add(a, _.tabar);
            return _;
            }

            var a = $(a.id);
        }

        /* if ( a.nodeName && a.nodeName!='A' ) {
            a = geTags(a, 'A')[0];
        } */

        _.click.apply(a);

    return _;
    };

    _.click = function(){/* to be call or apply only!! */
        if ( _.active && _.active.nodeName ) {
            if ( _.active==this ) {
                return true;
            }

            _.active.delClass('act');
            _.timer[_.active.id] = now(2);
        }

        this.addClass('act');

        var id = this.id,
            ot = _.tab$[id],
            dv = _.$[id];

        if ( typeof ot.data=='function' ) {
            if ( !ot.preload || _.timeout(this) ) {
                ot.preload = true;
                var dat = ot.data.apply(dv,[this]);
                if ( typeof dat=='string' ) {
                    dv.html(dat);
                } else if (typeof dat=='object' && dat.nodeType) {
                    dv.appendChild(dat);
                }
            }
        }

        _.togg.apply(this, [id]);
        _.active = this;

    return false;
    };

    _.togg = function(a){/* to be call or apply only!! */
        if ( !hop(_.$,a) ) {
            return false;
        }

        if ( _.active && _.active.nodeName ) {
            if ( _.active==this ) {
                return false;
            }
            var pd = _.active.id;//attr(_.active,'tabkey');

            if ( _.$[pd] && _.$[pd].nodeName ) {
                _.$[pd].className='off';
            }
        } else {
            for ( var v in _.$ ) {
                _.$[v].className = 'off';
            }
        }

        _.$[a].className = 'on';

    return true;
    };

    _.add = function(ot, el){
        if ( !ot || !el ) {
            return false;
        }

        if ( hop(_.$, ot.id) ) {
            return _.go(ot.id);
        }

        var li = elm('dd').setClass('item').appendTo(el);

        li.id = p(ot, 'id') && !$(ot.id) ? ot.id : 'itab_'+ now(2)*Math.random();
        if ( !p(ot, 'id') || ot.id!=li.id ) {
            ot.id = li.id;
        }

        if ( p(ot, 'css') ) {
            li.style.cssText = ot.css;
        }

        if ( !ot.notab ) {
            var a = elm('a').setClass('a').attr('href', ot.url||('#'+ li.id)).attr('tabkey',li.id).appendTo(li);
            if ( p(ot, 'tab', 'css') ) {
                a.style.cssText = ot.tab.css;
            }

            a.onclick = function(){return false;};

            _.timer[li.id] = now(2);

            if ( p(ot,'tab','cls') ) {
                if ( ot.tab.cls=='act' ) {
                    ot.preload=true;
                    if ( _.active && _.active.nodeName ) {
                        _.active.delClass('act');

                        var pd = _.active.id;

                        _.timer[pd] = now(2);
                    }

                    if ( _.$[pd] && _.$[pd].nodeName ) {
                        _.$[pd].className = 'off';
                    } else {
                        for ( var v in _.$ ) {
                            _.$[v].className = 'off';
                        }
                    }
                    _.active = li.addClass('act');
                }
            }

            li.onclick = function(ev){
                if ( _.click.apply(this, [ot.data]) ) {
                    return false;
                }

                if ( typeof ot.fn=='function' ) {
                    ot.fn.apply(this, [ot.data]);
                }

            return false;
            };

            if ( p(ot, 'ico', 'src') ) {
                var ico = elm('img').setClass('ico').attr('src', (_.icourl + ot.ico.src))
                        .attr('alt', ot.ico.alt||'').appendTo(a);
                if ( p(ot, 'ico', 'css') ) {
                    ico.style.cssText = ot.ico.css;
                }
            }

            if ( p(ot.tab, 'label') ) {
                var tx = elm('div').setClass('txt').attr('id',li.id +'_label')
                        .html(ot.tab.label).appendTo(a);
            }

            if ( p(ot,'key') ) {
                var em = elm('em').setClass('ikey').html('(<kbd class=kbd>'+ ot.key +'<\/kbd>)').appendTo(a);
            }

            /* tabs data */
            var dv = elm('div').setClass(_.active==li ? 'on':'off')
                    .attr('id','itab_'+ li.id).appendTo(_.tabdata);

            if ( typeof ot.data=='function' && !!ot.preload ) {
                var dat = ot.data.apply(dv,[a]);
                if ( typeof dat=='string' ) {
                    dv.html(dat);
                } else if (typeof dat=='object' && dat.nodeType) {
                    dv.appendChild(dat);
                }
            } else if ( typeof ot.data=='string' ) {
                dv.html( ot.data );
            } else if ( typeof ot.data=='object' && ot.data.nodeType ) {
                dv.appendChild(ot.data);
            }

            /* tab close */
            if ( !ot.locked ) {
                var xx = elm('div').setClass('iclose').attr('title', 'X')
                        .appendTo(a);

                xx.style.cssText = 'background:url('+ _.icourl+_.tabclose +') 0 0 no-repeat;';

                xx.onmouseover = function(){
                    this.style.backgroundPosition = '-16px 0';
                };

                xx.onmouseout = function(){
                    this.style.backgroundPosition='0 0';
                };

                xx.onclick=function(){
                    if ( _.num<2 ) {
                        return false;
                    }
                    li.onclick = function(){return false;};

                    try {
                        delete _.$[li.id];
                        delete _.tab$[li.id];
                        delete _.timer[li.id];
                        li.empty().remove();
                        dv.empty().remove();
                    } catch (ex) {
                    }

                    if ( _.active==li ) {
                        _.active = null;
                        var tabm='',tmax=0;
                        for ( var x in _.timer ) {
                            if (_.timer[x]>tmax) {
                                tmax = _.timer[x];
                                tabm = x;
                            }
                        }
                        tabm!='' && _.click.apply($(tabm), []);
                    }

                    _.num--;

                return false;
                };
            }

            _.num++;

            _.tab$[li.id] = ot;
            _.$[li.id] = dv;

        } else {
            var dv = elm('div').appendTo(li);
            dv.id = ot.id +'_div';
            if ( typeof ot.data=='function' ) {
                var dat = ot.data.apply(dv,[dv]);
                if ( typeof dat=='string' ) {
                    dv.innerHTML = dat;
                }
            } else if ( typeof ot.data=='string' ) {
                dv.innerHTML = ot.data;
            } else if ( typeof ot.data=='object' && ot.data.nodeType ) {
                dv.appendChild(ot.data);
            }
        }

        if ( ot.rtl ) {
            li.addClass('rtl');
        }

    return li;
    };

    _.init = function(){
        _.root = elm('div').appendTo(_.elem).setClass('itab');

        _.id = _.root.id = p(_,'id') && !$(_.id) ? _.id : ('tab'+ now(3));

        _.tabdata = elm('div').setClass('itab').appendTo(_.target);

        _.tabar = elm('dl').setClass('ibar').appendTo(_.root);

        for ( var z in _.tabs ) {
            _.add(_.tabs[z], _.tabar);
        }

        if ( _.active==null && z ) {
            var tabm = '';
            if (_.timer) {
                for ( var x in _.timer ) {
                    if (!tmin) {
                        var tmin = _.timer[x];
                    }
                    if (_.timer[x]<=tmin) {
                        tmin = _.timer[x];
                        tabm = x;
                    }
                }
            }

            tabm!='' && _.click.apply($(tabm), []);
        }

    return _;
    };

}